refactor: standardize tsconfig hierarchy, inline handle* functions, improve SvelteKit apps#1542
Merged
refactor: standardize tsconfig hierarchy, inline handle* functions, improve SvelteKit apps#1542
Conversation
…d reorganize files Split the 538-line createNotesState into three focused factories (foldersState, notesState, viewState) with a clean dependency DAG. Extract workspace schema from client instantiation, co-locate editor utilities with the Editor component, and consolidate date utils. All component imports updated to use the split state modules.
…scribing NoteCard, data-driven Editor toolbar
NoteList now takes notes/title/showControls props instead of branching on
view mode internally. NoteCard derives isDeleted from note.deletedAt and
accepts isSelected/onSelect props, dropping the viewState import entirely.
Editor toolbar uses snippets for the 12 repeated button patterns, cutting
150 lines of copy-paste to 20 lines of snippet calls. Sort dropdown is
data-driven via array + {#each}. Svelte skill updated with three new
patterns: prop-first derivation, view-mode branching limit, data-driven
repetitive markup.
…ead folderName branch Extract FolderMenuItem.svelte from Sidebar per the self-contained component pattern — each folder row now owns its own rename editing state and delete confirmation dialog instead of sharing a single dialog managed by the parent. Sidebar drops from 212 to 93 lines. Also remove the dead isRecentlyDeletedView branch from viewState.folderName since the parent now passes the title directly.
…inlining rule Inline 7 single-use functions across 4 components: startRename/cancelRename in FolderMenuItem, toggleHeading/toggleListType in Editor, handleKeydown in NoteList and +page. commitRename stays extracted (used 2x: keydown + blur). Update Svelte skill to replace the narrow 'no handle* functions' rule with a broader single-use inlining rule: inline by default, keep extracted only with JSDoc + semantic name. Multi-use functions always stay extracted.
Grep for 'function handle' found 20 handle* functions in .svelte files across the monorepo. 17 were single-use wrappers adding unnecessary indirection — inlined at the call site. FileTree.handleKeydown renamed to navigateFileTree with JSDoc (75-line keyboard nav switch, legitimate exception). Two skipped: TransformationPickerBody (imperative onMount listener) and UpdateDialog (30-line download flow). Apps touched: opensidian (6 files), tab-manager (2), fuji (2), landing (1). Also adds docs/articles/grep-for-handle-functions.md explaining the grep command and the smell pattern.
…to @epicenter/svelte
Rename @epicenter/svelte-utils → @epicenter/svelte and add two new
reactive utilities that eliminate boilerplate observer patterns across
all apps.
fromKv wraps a single KV key into a { current } box (mirrors Svelte 5's
fromStore). fromTable returns a SvelteMap with granular per-row updates
via the table observer, replacing the wholesale array re-read pattern.
Migrated 8 files across honeycrisp, fuji, and tab-manager from manual
$state + observe → fromKv/fromTable. All derived arrays cached via
$derived to avoid re-creating on every getter access.
Also standardizes tsconfig lib from ES2022 → ESNext across 12 packages.
….filter()) TC39 Iterator Helpers (Stage 4) are fully typed in TS 5.9 via lib.esnext.iterator.d.ts. MapIterator extends IteratorObject which provides .filter(), .map(), .find(), .toArray(), .some(), .every(), .reduce(), .take(), .drop(), .flatMap() — no spread needed. Replaces all [...map.values()] patterns with map.values().toArray(). Sort still requires materialization (.toArray().sort()) since sort needs random access. Updated svelte skill with iterator helpers guidance.
… table state pattern to Svelte skill
Iterator helpers (.toArray(), .filter(), .find() on IteratorObject) are
a TS/JS language feature — moved to typescript skill where it belongs.
Svelte skill now documents the fromTable → $derived → getter naming
convention: {name}Map → {name} → get {name}(). Consolidated from ~80
lines of mixed TS/Svelte content into ~45 focused lines.
The workspace-api skill covered schema definition thoroughly but said nothing about reading, writing, or observing data. Added table CRUD (get, getAllValid, set, update, delete, has, count), KV CRUD (get, set), and observation patterns. Cross-references svelte skill for fromTable/ fromKv reactive wrappers.
…er packages Strip tsc --init boilerplate from base (115→32 lines). Update target to ESNext. Add tsconfig.base.dom.json extending base with DOM and DOM.Iterable libs for browser-only packages.
…t options These packages don't use browser DOM APIs—switched from standalone configs to extending tsconfig.base.json. Removed ~10 options per package that were already inherited from base.
CLI exporter—no browser DOM APIs needed.
These options were duplicated in 10/14 child configs. Moving them to base eliminates the redundancy. Options that conflict with noEmit (declaration, declarationMap, inlineSources) stay per-package since library packages must opt into emit individually.
…lat API surface Removes the nested `actions` sub-object from bookmark, saved-tab, browser, and filesystem state modules. All mutation methods now live directly on the returned object, matching the existing pattern in Honeycrisp (folders, notes, view) and Whispering (deviceConfig, etc.). Updates all consumer components to drop the `.actions.` accessor. Adds reactive state module conventions to the svelte skill.
Shared config for packages that emit declarations: noEmit:false, declaration, declarationMap, inlineSources. Eliminates duplication across constants, ui, and vault. Also removes redundant module:ESNext from vault (already inherited from base).
…ir, composite to shared configs allowJs and allowImportingTsExtensions → base (used by 9 and 5 packages respectively). outDir:dist and composite:true → base.lib (standard for all library packages). Removes 20+ redundant overrides across child configs.
Standardizes Bun runtime types across all SvelteKit apps (fuji, honeycrisp, whispering). Opensidian already had it. Monorepo runs on Bun so all apps should have the types available.
Resolve conflicts in opensidian components by taking main's new features (CommandPalette component, inline editing, deleted dialogs) while preserving our branch's flat API (fsState.selectFile instead of fsState.actions.selectFile). Flatten all fsState.actions.* refs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three loosely-related threads that landed on the same branch during a cleanup pass. They share the same theme: less indirection, tighter types, fewer places to configure the same thing.
tsconfig hierarchy
New three-tier config structure replaces per-package duplication:
bun-typesto the SvelteKit apps for consistencyHoneycrisp refactor
App and component cleanup
handle*wrappers into direct event handlersSvelte and tooling consistency
fromKv/fromTablebindings in@epicenter/svelte